#include<iostream>
#include<future>
#include <vector>
#include <queue>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <stdexcept>

class ThreadPool {
public:
    // 构造函数：创建指定数量的工作线程
    ThreadPool(size_t threads) : stop(false) {
        std::cout << "创建线程池，线程数: " << threads << std::endl;
        
        for(size_t i = 0; i < threads; ++i) {
            // 为每个线程分配工作函数
            workers.emplace_back([this, i] {
                std::cout << "工作线程 " << i << " 启动" << std::endl;
                
                // 线程主循环
                for(;;) {
                    std::function<void()> task;
                    
                    {
                        // 获取任务队列的锁
                        std::unique_lock<std::mutex> lock(this->queue_mutex);
                        
                        // 等待条件变量：停止信号或新任务到达
                        this->condition.wait(lock, [this] {
                            return this->stop || !this->tasks.empty();
                        });
                        
                        // 检查是否需要终止线程
                        if(this->stop && this->tasks.empty()) {
                            std::cout << "工作线程终止" << std::endl;
                            return;
                        }
                        
                        // 从队列中取出任务
                        task = std::move(this->tasks.front());
                        this->tasks.pop();
                        std::cout << "任务被取出，剩余任务数: " << this->tasks.size() << std::endl;
                    }
                    
                    // 执行任务（在锁外执行，避免长时间持有锁）
                    std::cout << "开始执行任务..." << std::endl;
                    task();
                    std::cout << "任务执行完成" << std::endl;
                }
            });
        }
    }

    // 任务提交函数模板
    template<class F, class... Args>
    auto enqueue(F&& f, Args&&... args) 
        -> std::future<typename std::result_of<F(Args...)>::type> {
        
        // 推导返回类型
        using return_type = typename std::result_of<F(Args...)>::type;
        
        // 创建packaged_task来包装用户函数
        // 使用shared_ptr使得任务可以在lambda中安全拷贝
        auto task = std::make_shared<std::packaged_task<return_type()>>(
            std::bind(std::forward<F>(f), std::forward<Args>(args)...)
        );
            
        // 获取与任务关联的future
        std::future<return_type> res = task->get_future();
        
        {
            // 锁保护任务队列
            std::unique_lock<std::mutex> lock(queue_mutex);
            
            // 检查线程池是否已停止
            if(stop) {
                throw std::runtime_error("不能在已停止的线程池上添加任务");
            }
            
            // 将任务包装成void()类型并加入队列 将任务包装成无参数无返回值的lambda
            tasks.emplace([task](){ 
                (*task)();  // 调用packaged_task
            });
            
            std::cout << "新任务加入队列，总任务数: " << tasks.size() << std::endl;
        }
        
        // 通知一个等待的工作线程
        condition.notify_one();
        return res;
    }

    // 析构函数：优雅关闭线程池
    ~ThreadPool() {
        std::cout << "线程池析构开始..." << std::endl;
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            stop = true;  // 设置停止标志
        }
        
        condition.notify_all();  // 唤醒所有等待的线程
        
        // 等待所有线程完成
        for(std::thread &worker : workers) {
            worker.join();
        }
        std::cout << "线程池析构完成" << std::endl;
    }

private:
    std::vector<std::thread> workers;  // 工作线程容器
    std::queue<std::function<void()>> tasks;  // 任务队列
    
    std::mutex queue_mutex;  // 保护任务队列的互斥锁
    std::condition_variable condition;  // 线程间通信的条件变量
    bool stop;  // 停止标志
};


#include <chrono>
#include <random>

// 示例1：基础任务执行
void basic_usage() {
    std::cout << "=== 基础使用示例 ===" << std::endl;
    
    // 创建4个线程的线程池
    ThreadPool pool(4);
    
    // 提交多个任务
    std::vector<std::future<int>> results;
    
    for(int i = 0; i < 8; ++i) {
        results.emplace_back(
            pool.enqueue([i] {
                std::cout << "任务 " << i << " 在线程 " 
                         << std::this_thread::get_id() << " 执行" << std::endl;
                std::this_thread::sleep_for(std::chrono::milliseconds(500));
                return i * i;
            })
        );
    }
    
    // 获取所有结果
    for(size_t i = 0; i < results.size(); ++i) {
        std::cout << "任务 " << i << " 结果: " << results[i].get() << std::endl;
    }
}

// 示例2：带异常处理的任务
void exception_handling() {
    std::cout << "\n=== 异常处理示例 ===" << std::endl;
    
    ThreadPool pool(2);
    
    auto task1 = pool.enqueue([]() -> int {
        throw std::runtime_error("任务执行出错!");
        return 42;
    });
    
    auto task2 = pool.enqueue([]() -> int {
        return 100;
    });
    
    try {
        auto result1 = task1.get();
        std::cout << "任务1结果: " << result1 << std::endl;
    } catch (const std::exception& e) {
        std::cout << "捕获异常: " << e.what() << std::endl;
    }
    
    auto result2 = task2.get();
    std::cout << "任务2结果: " << result2 << std::endl;
}

// 示例3：模拟耗时任务
void heavy_tasks() {
    std::cout << "\n=== 耗时任务示例 ===" << std::endl;
    
    ThreadPool pool(std::thread::hardware_concurrency());
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(100, 500);
    
    auto start = std::chrono::high_resolution_clock::now();
    
    std::vector<std::future<int>> tasks;
    for(int i = 0; i < 10; ++i) {
        tasks.emplace_back(pool.enqueue([i, &dis, &gen] {
            int sleep_time = dis(gen);
            std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time));
            std::cout << "任务 " << i << " 耗时 " << sleep_time << "ms" << std::endl;
            return i;
        }));
    }
    
    // 等待所有任务完成
    for(auto& task : tasks) {
        task.wait();
    }
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    std::cout << "总耗时: " << duration.count() << "ms" << std::endl;
}

// 示例4：不同返回类型的任务
void various_return_types() {
    std::cout << "\n=== 不同返回类型示例 ===" << std::endl;
    
    ThreadPool pool(2);
    
    // 返回int
    auto int_task = pool.enqueue([]() -> int {
        return 42;
    });
    
    // 返回string
    auto string_task = pool.enqueue([]() -> std::string {
        return "Hello, ThreadPool!";
    });
    
    // 返回void
    auto void_task = pool.enqueue([]() {
        std::cout << "void任务执行完成" << std::endl;
    });
    
    // 返回自定义类型
    struct Result {
        int value;
        std::string message;
    };
    
    auto custom_task = pool.enqueue([]() -> Result {
        return {100, "Success"};
    });
    
    std::cout << "int结果: " << int_task.get() << std::endl;
    std::cout << "string结果: " << string_task.get() << std::endl;
    void_task.wait(); // void任务使用wait而不是get
    auto custom_result = custom_task.get();
    std::cout << "自定义结果: " << custom_result.value << ", " 
              << custom_result.message << std::endl;
}

int main() {
    basic_usage();
    exception_handling();
    heavy_tasks();
    various_return_types();
    
    return 0;
}